package com.example.takeaway.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.takeaway.common.ResponseEnum;
import com.example.takeaway.context.UserInfoContext;
import com.example.takeaway.converter.DishConverter;
import com.example.takeaway.exception.BusException;
import com.example.takeaway.mapper.CategoryMapper;
import com.example.takeaway.mapper.DishItemSpecificationMapper;
import com.example.takeaway.mapper.DishMapper;
import com.example.takeaway.mapper.SpecificationMapper;
import com.example.takeaway.model.PageVO;
import com.example.takeaway.model.bo.Category;
import com.example.takeaway.model.bo.Dish;
import com.example.takeaway.model.bo.DishItemSpecification;
import com.example.takeaway.model.bo.Specification;
import com.example.takeaway.model.dto.DishDTO;
import com.example.takeaway.model.dto.DishEditorDTO;
import com.example.takeaway.model.dto.DishPageQuery;
import com.example.takeaway.model.vo.DishVO;
import com.example.takeaway.model.vo.SpecificationVO;
import com.example.takeaway.service.DishService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜品表 服务实现类
 * </p>
 *
 * @author 邢晨旭
 * @since 2023-10-12
 */
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Resource
    DishConverter converter;
    @Resource
    DishItemSpecificationMapper dishItemSpecificationMapper;
    @Resource
    CategoryMapper categoryMapper;
    @Resource
    SpecificationMapper specificationMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addDish(DishDTO param) {
        //判断菜品名称是否存在
        Integer countDish = baseMapper.countDishByName(param.getDishName());
        if (countDish > 0) {
            throw new BusException(ResponseEnum.DISH_NAME_EXIST);
        }
        check(param);
        //新增菜品
        Dish dish = converter.toDish(param);
        baseMapper.insert(dish);
        //新增菜品规格关联
        List<DishItemSpecification> list = new ArrayList<>();
        param.getSpecificationIds().forEach(specificationId -> {
            DishItemSpecification specification = new DishItemSpecification();
            specification.setDishId(dish.getId());
            specification.setSpecificationId(specificationId);
            list.add(specification);
        });
        dishItemSpecificationMapper.insertBatch(list);
    }

    /**
     * 校验菜品信息(关联的的分类-规格是否存在)
     *
     * @param param
     */
    private void check(DishDTO param) {
        //判断菜品分类是否存在
        Category category = categoryMapper.queryById(param.getCategoryId());
        if (category == null || category.getIsDeleted() == 1) {
            throw new BusException(ResponseEnum.CATEGORY_NOT_EXIST);
        }
        //判断规格是否存在
        if (param.getSpecificationIds() != null && param.getSpecificationIds().size() > 0) {
            List<Specification> specificationList = specificationMapper.selectBatchIds(param.getSpecificationIds());
            if (specificationList.size() != param.getSpecificationIds().size()) {
                throw new BusException(ResponseEnum.SPECIFICATION_NOT_FOUND);
            }
            specificationList.forEach(specification -> {
                if (specification.getIsDeleted() == 1) {
                    throw new BusException(ResponseEnum.SPECIFICATION_NOT_FOUND);
                }
            });
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateDishById(DishEditorDTO param) {
        //判断菜品是否存在
        Dish oldDish = baseMapper.selectById(param.getId());
        if (oldDish == null || oldDish.getIsDeleted() == 1) {
            throw new BusException(ResponseEnum.DISH_NOT_EXIST);
        }
        //判断菜品是否启用
        if (oldDish.getStatus() == 1) {
            throw new BusException(ResponseEnum.DISH_STATUS_ERROR);
        }
        //判断菜品名称是否重复
        Integer countDish = baseMapper.countDishByIdAndName(param.getDishName(), param.getId());
        if (countDish > 0) {
            throw new BusException(ResponseEnum.DISH_NAME_EXIST);
        }
        //校验菜品信息(关联的的分类-规格是否存在)
        check(param);
        //修改菜品
        Dish dish = converter.toDish(param);
        baseMapper.updateById(dish);
        //查询旧数据
        List<Long> oldIds = dishItemSpecificationMapper.querySpecificationIdsByDishId(param.getId());
        //求差集
        List<Long> addIds = param.getSpecificationIds().stream().filter(id -> !oldIds.contains(id)).collect(Collectors.toList());
        List<Long> delIds = oldIds.stream().filter(id -> !param.getSpecificationIds().contains(id)).collect(Collectors.toList());
        //新增关联的规格信息
        if (addIds.size() > 0) {
            List<DishItemSpecification> list = new ArrayList<>();
            addIds.forEach(specificationId -> {
                DishItemSpecification specification = new DishItemSpecification();
                specification.setDishId(dish.getId());
                specification.setSpecificationId(specificationId);
                list.add(specification);
            });
            dishItemSpecificationMapper.insertBatch(list);
        }
        //删除关联的规格信息
        if (delIds.size() > 0) {
            dishItemSpecificationMapper.deleteBatchByDishIdAndSpecificationIds(param.getId(), delIds);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteDishById(Long id) {
        //判断菜品是否存在
        Dish oldDish = baseMapper.selectById(id);
        if (oldDish == null || oldDish.getIsDeleted() == 1) {
            return;
        }
        //判断菜品是否启用
        if (oldDish.getStatus() == 1) {
            throw new BusException(ResponseEnum.DISH_STATUS_ERROR);
        }
        //删除菜品
        baseMapper.deleteDishById(id);
        //删除关联的规格信息
        dishItemSpecificationMapper.deleteBatchByDishIdAndSpecificationIds(id, null);
    }

    @Override
    public DishVO getDishById(Long id) {
        //查询菜品信息
        DishVO dishVO = baseMapper.queryById(id);
        if (dishVO == null) {
            throw new BusException(ResponseEnum.DISH_NOT_EXIST);
        }
        //查询关联的规格信息
        List<SpecificationVO> specificationList = dishItemSpecificationMapper.querySpecificationsByDishId(id);
        dishVO.setSpecifications(specificationList);
        return dishVO;
    }

    @Override
    public PageVO<DishVO> queryPage(DishPageQuery param) {
        Page<DishVO> pageDTO = PageDTO.of(param.getPage(), param.getSize());
        List<DishVO> list = baseMapper.queryPage(pageDTO, param, UserInfoContext.get().getUserId());
        PageVO<DishVO> pageVO = new PageVO<>();
        pageVO.setPage(param.getPage());
        pageVO.setSize(param.getSize());
        pageVO.setTotal(pageDTO.getTotal());
        pageVO.setList(list);
        return pageVO;
    }

    @Override
    public List<DishVO> queryList(Long categoryId) {
        return baseMapper.queryList(categoryId,1);
    }
}
